﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Windows.Controls;
using CThru.Silverlight;
using TypeMock.ArrangeActAssert;
using Api.ContentProvider;

namespace DefaultContentProvider.Test.Unit
{
    public class CompositeContentProviderTests
    {
        private CompositeContentProvider contentProvider;

        [SetUp, SilverlightUnitTest]
        public void Setup()
        {
            contentProvider = CreateCompositeContentProvider();
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void IsItemTypeSupported_NullPassed_ThrowArgumentNullException()
        {
            contentProvider.IsItemTypeSupported(null);
        }

        [Test, SilverlightUnitTest]
        [ExpectedException(typeof(ArgumentNullException))]
        public void GetItemsMapping_NullPassed_ThrowArgumentNullException()
        {
            contentProvider.GetItemsMapping(null);
        }

        [Test, SilverlightUnitTest]
        public void IsItemTypeSupported_NotKnownTypePassesd_ReturnsFalse()
        {
            var result = contentProvider.IsItemTypeSupported("agegebeb");

            Assert.False(result);
        }

        [Test, SilverlightUnitTest]
        [ExpectedException(typeof(KeyNotFoundException))]
        public void GetItemsMapping_NotKnownTypePassesd_FunctionThrowsKeyNotFound()
        {
            var mapping = contentProvider.GetItemsMapping("agegebeb");

            var control = mapping("http://imageworld.com/img/123");
        }

        [Test, SilverlightUnitTest]
        public void IsItemTypeSupported_KnownTypeInFirstContentProvider_ReturnsTrue()
        {
            var compositeContentProvider = CreateCompositeContentProvider();

            var result = compositeContentProvider.IsItemTypeSupported("text");

            Assert.True(result);
        }

        [Test, SilverlightUnitTest]
        public void GetItemsMapping_KnownTypeInFirstContentProvider_ExceptionNotThrown()
        {
            var compositeContentProvider = CreateCompositeContentProvider();

            var result = compositeContentProvider.GetItemsMapping("text");
        }

        [Test, SilverlightUnitTest]
        public void IsItemTypeSupported_KnownTypeInSecondDontentProvider_ReturnsTrue()
        {
            var compositeContentProvider = CreateCompositeContentProvider();

            var result = compositeContentProvider.IsItemTypeSupported("image");

            Assert.True(result);
        }

        [Test, SilverlightUnitTest]
        public void GetItemsMapping_KnownTypeInSecondContentProvider_ExceptionNotThrown()
        {
            var compositeContentProvider = CreateCompositeContentProvider();

            var result = compositeContentProvider.GetItemsMapping("image");
        }

        private static CompositeContentProvider CreateCompositeContentProvider()
        {
            var contentProvinerNo1 = Isolate.Fake.Instance<IContentProvider>();
            Isolate.WhenCalled(() => contentProvinerNo1.IsItemTypeSupported("image")).WithExactArguments().DoInstead(context => false);
            Isolate.WhenCalled(() => contentProvinerNo1.GetItemsMapping("image")).WithExactArguments().WillThrow(new KeyNotFoundException());
            Isolate.WhenCalled(() => contentProvinerNo1.IsItemTypeSupported("text")).WithExactArguments().DoInstead(context => true);
            Isolate.WhenCalled(() => contentProvinerNo1.GetItemsMapping("text")).WithExactArguments().DoInstead(context => (value => new TextBlock()));

            var contentProvinerNo2 = Isolate.Fake.Instance<IContentProvider>();
            Isolate.WhenCalled(() => contentProvinerNo2.IsItemTypeSupported("image")).WithExactArguments().DoInstead(context => true);
            Isolate.WhenCalled(() => contentProvinerNo2.GetItemsMapping("image")).WithExactArguments().DoInstead(context => (value => new Image()));

            var compositeContentProvider = new CompositeContentProvider(new IContentProvider[] { contentProvinerNo1, contentProvinerNo2 });
            return compositeContentProvider;
        }
    }
}
